﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;

namespace Mutex
{
    class Program
    {
        // Create a new Mutex. The creating thread does not own the mutex.
        private static System.Threading.Mutex mut = new System.Threading.Mutex();
        private const int numIterations = 1;
        private const int numThreads = 3;

        static void Main(string[] args)
        {
            StartThreads();
            Console.ReadLine();
        }

        private static void StartThreads()
        {
            // Create the threads that will use the protected resource.
            for (int i = 0; i < numThreads; i++)
            {
                Thread newThread = new Thread(new ThreadStart(ThreadProc));
                newThread.Name = String.Format("Thread{0}", i + 1);
                newThread.Start();
            }

            // The main thread returns to Main and exits, but the application continues to
            // run until all foreground threads have exited.
        }

        private static void ThreadProc()
        {
            for (int i = 0; i < numIterations; i++)
            {
                UseResource();
            }
        }

        /// <summary>
        /// 用户资源，Mutex互斥
        /// </summary>
        private static void UseResource()
        {
            // Wait until it is safe to enter, and do not enter if the request times out.
            Console.WriteLine("{0} is requesting the mutex", Thread.CurrentThread.Name);
            if (mut.WaitOne(10000))
            {
                Console.WriteLine("{0} has entered the protected area",Thread.CurrentThread.Name);

                // Place code to access non-reentrant resources here.

                // Simulate some work.
                Thread.Sleep(5000);

                Console.WriteLine("{0} is leaving the protected area",Thread.CurrentThread.Name);

                // Release the Mutex.
                mut.ReleaseMutex();
                Console.WriteLine("{0} has released the mutex",Thread.CurrentThread.Name);
            }
            else
            {
                Console.WriteLine("{0} will not acquire the mutex",Thread.CurrentThread.Name);
            }
        }
    }
}
